<!DOCTYPE html>
<html>
<head>
    <title>Electric Field Lines</title>
</head>
<body>
    <canvas id="electricFieldCanvas" width="800" height="450"></canvas>
    <script>
        const canvas = document.getElementById('electricFieldCanvas');
        const ctx = canvas.getContext('2d');

        // Clear canvas
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1.5;

        // Function to draw an arrowhead at a point (x,y) with a given angle and size
        function drawArrowhead(x, y, angle, size) {
            ctx.save();
            ctx.translate(x, y);
            ctx.rotate(angle);
            ctx.beginPath();
            // The two lines of the V-shape that form the arrow
            ctx.moveTo(0, 0);
            ctx.lineTo(-size, -size / 2.5);
            ctx.moveTo(0, 0);
            ctx.lineTo(-size, size / 2.5);
            ctx.stroke();
            ctx.restore();
        }

        // Charge positions and radius
        const q1 = { x: 550, y: 225, r: 25 };
        const q2 = { x: 250, y: 225, r: 25 };
        
        // Draw the circles for the charges
        ctx.beginPath();
        ctx.arc(q1.x, q1.y, q1.r, 0, 2 * Math.PI);
        ctx.stroke();

        ctx.beginPath();
        ctx.arc(q2.x, q2.y, q2.r, 0, 2 * Math.PI);
        ctx.stroke();

        // Draw the labels for the charges
        ctx.fillStyle = 'black';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        
        // Label q1
        ctx.font = 'italic 22px serif';
        ctx.fillText('q', q1.x - 6, q1.y);
        ctx.font = 'italic 16px serif';
        ctx.fillText('1', q1.x + 7, q1.y + 8);

        // Label q2
        ctx.font = 'italic 22px serif';
        ctx.fillText('q', q2.x - 6, q2.y);
        ctx.font = 'italic 16px serif';
        ctx.fillText('2', q2.x + 7, q2.y + 8);

        // --- Draw Field Lines ---
        ctx.lineWidth = 1.2;

        // Lines terminating on q2 (from left) - 3 lines
        // 1. Straight line from left
        ctx.beginPath();
        ctx.moveTo(20, q2.y);
        ctx.lineTo(q2.x - q2.r, q2.y);
        ctx.stroke();
        drawArrowhead(q2.x - q2.r - 100, q2.y, 0, 10);

        // 2. Curved line from top-left
        ctx.beginPath();
        ctx.moveTo(q2.x - 150, q2.y - 200);
        ctx.quadraticCurveTo(q2.x - 100, q2.y - 50, q2.x - q2.r * 0.707, q2.y - q2.r * 0.707);
        ctx.stroke();
        drawArrowhead(q2.x-80, q2.y-55, 0.7, 10);
        
        // 3. Curved line from bottom-left
        ctx.beginPath();
        ctx.moveTo(q2.x - 150, q2.y + 200);
        ctx.quadraticCurveTo(q2.x - 100, q2.y + 50, q2.x - q2.r * 0.707, q2.y + q2.r * 0.707);
        ctx.stroke();
        drawArrowhead(q2.x-80, q2.y+55, -0.7, 10);

        // Lines between q1 and q2 - 3 lines
        // 1. Straight line
        ctx.beginPath();
        ctx.moveTo(q1.x - q1.r, q1.y);
        ctx.lineTo(q2.x + q2.r, q2.y);
        ctx.stroke();
        drawArrowhead(q2.x + q2.r + 100, q2.y, Math.PI, 10);
        
        // 2. Curved line above
        ctx.beginPath();
        ctx.moveTo(q1.x - q1.r*0.707, q1.y - q1.r*0.707);
        ctx.bezierCurveTo(q1.x - 80, q1.y - 80, q2.x + 80, q2.y - 80, q2.x + q2.r*0.707, q2.y - q2.r*0.707);
        ctx.stroke();
        drawArrowhead(400, 165, Math.PI, 10);
        
        // 3. Curved line below
        ctx.beginPath();
        ctx.moveTo(q1.x - q1.r*0.707, q1.y + q1.r*0.707);
        ctx.bezierCurveTo(q1.x - 80, q1.y + 80, q2.x + 80, q2.y + 80, q2.x + q2.r*0.707, q2.y + q2.r*0.707);
        ctx.stroke();
        drawArrowhead(400, 285, Math.PI, 10);
        
        // Lines originating from q1 (to right) - 5 lines
        // 1 & 2. Two close lines to the right
        ctx.beginPath();
        ctx.moveTo(q1.x + q1.r, q1.y);
        ctx.lineTo(q1.x + 230, q1.y - 10);
        ctx.stroke();
        drawArrowhead(q1.x + 150, q1.y - 6, -0.05, 10);

        ctx.beginPath();
        ctx.moveTo(q1.x + q1.r, q1.y);
        ctx.lineTo(q1.x + 230, q1.y + 10);
        ctx.stroke();
        drawArrowhead(q1.x + 150, q1.y + 6, 0.05, 10);

        // 3. Line to top-right (shallow)
        ctx.beginPath();
        ctx.moveTo(q1.x + q1.r * 0.707, q1.y - q1.r * 0.707);
        ctx.lineTo(q1.x + 200, q1.y - 120);
        ctx.stroke();
        drawArrowhead(q1.x + 110, q1.y - 70, -0.5, 10);

        // 4. Line to top-right (steep)
        ctx.beginPath();
        ctx.moveTo(q1.x, q1.y - q1.r);
        ctx.lineTo(q1.x + 120, q1.y - 180);
        ctx.stroke();
        drawArrowhead(q1.x + 60, q1.y - 100, -Math.PI/3, 10);

        // 5. Line to bottom-right (shallow)
        ctx.beginPath();
        ctx.moveTo(q1.x + q1.r * 0.707, q1.y + q1.r * 0.707);
        ctx.lineTo(q1.x + 200, q1.y + 120);
        ctx.stroke();
        drawArrowhead(q1.x + 110, q1.y + 70, 0.5, 10);

    </script>
</body>
</html>